package expressions;

import values.Boolean;
import values.Value;
import base.AST;
import base.Environment;
import base.Interpreter;

public class NotGate implements Expression {

	private AST son;

	/**
	 * Creates an expression that represents the logical value NOT eval(son)
	 * 
	 * @param son
	 *            a Value or an Expression
	 */

	public NotGate(AST son) {
		assert son instanceof Value || son instanceof Expression;

		this.son = son;
	}

	/**
	 * Returns !eval(son) if eval(son) is a boolean. Throws a
	 * BadExpressionValueException otherwise.
	 * @throws BadExpressionException 
	 */

	public Value eval(Environment env) throws BadExpressionException {

		Boolean a = Interpreter.getBoolean(this.son, env);

		if (a != null)
			return new Boolean(!a.eval());
		else
			throw new BadExpressionException(
					"Trying to apply logical NOT on non-boolean value");
	}

}
